#include<iostream>
#include<cstdio>
#include<sys/types.h>
#include<sys/stat.h>
#include<cstring>
#include<errno.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/stat.h>



using namespace std;

#define Mode 0666 //指定命名管道的权限
#define Path "./fifo" //路径名

class Fifo
{
public:
    Fifo(const string& path) 
        :_path(path)
    {
        umask(0);
        int n = mkfifo(Path, Mode); //创建命名管道
        if(n == 0) 
        {
            cout << "mkfifo success!" << endl;
        }
        else
        {
            cout << "mkfifo failed! errno: " << errno << "errdesc: " << strerror(errno) << endl; 
        }
    }

    ~Fifo() 
    {
        int n = unlink(Path); //删除命名管道
        if(n == 0)
        {
            cout << "remove file success!" << endl;
        }
        else
        {
            cout << "remove file failed! errno: " << errno << "errdesc: " << strerror(errno) << endl; 
        }

    }

private:
    string _path;
};

class Sysn //在共享内存中使用管道(包含同步、互斥机制),保护共享资源
{
public:
    Sysn():wfd(-1),rfd(-1)
    { }

    void OpenWriteorDie() //以只写的方式打开管道
    {
        wfd = open(Path, O_WRONLY);
        if(wfd < 0)
            exit(4);
    }

    void OpenReadorDie() //以只读的方式打开管道
    {
        rfd = open(Path, O_RDONLY);
        if(rfd < 0)
            exit(5);
    }

    bool Wait() //服务福端等待客服端写入完成
    {
        int flag = true;
        int c = 0;
        int n = read(rfd, &c, sizeof(c));
        if(n == sizeof(c))
            cout << "Server wake, begin read shm!" << endl;
        else if(n == 0)
            flag = false;
        else
            flag = false;

        return flag;
    }

    void Wakeup() //客户端写完,唤醒服务端
    {
        int c = 0;
        int n = write(wfd, &c, sizeof(c));
        if(n == -1)
        {
            cerr << "write failed" <<  endl;
            exit(3);
        }
        cout << "Server Wake......" << endl;
    }

private:
    int wfd;
    int rfd;
};